<script setup lang="ts">
import { onMounted } from 'vue';

import AMapLoader from '@amap/amap-jsapi-loader';

import mockData from '#/assets/mockGeo.json';

// 声明全局 Loca 类型
declare global {
  interface Window {
    Loca: any;
  }
}

// 定义坐标点类型
interface Coordinate {
  properties: {
    rank: number;
  };
}

// 定义特征类型
interface Feature {
  coordinates: Coordinate[];
}

// 计算路口rank之和
function sum(arr: Coordinate[]): number {
  var sum = 0;
  arr.forEach((a: Coordinate) => {
    sum += a.properties.rank;
  });
  return sum;
}

// 提取计算高度和颜色的索引函数
function getLevel(ranks: number) {
  if (ranks < 20) return 0;
  if (ranks < 40) return 1;
  if (ranks < 60) return 2;
  if (ranks < 80) return 3;
  if (ranks < 100) return 4;
  if (ranks < 120) return 5;
  if (ranks < 130) return 6;
  return 7;
}

onMounted(() => {
  AMapLoader.load({
    key: 'a190f2e9a9b103db926fd63a5fe81b53', // 替换为你的高德地图 API 密钥
    version: '2.0', // 高德地图 JS API 版本
    plugins: ['AMap.HeatMap'], // 加载插件
    Loca: {
      version: '2.0', // Loca 版本
    },
  })
    .then((AMap) => {
      const map = new AMap.Map('map', {
        zoom: 11.43,
        center: [113.625368, 34.7466],
        pitch: 55,
        rotation: 20,
        viewMode: '3D',
        mapStyle: 'amap://styles/45311ae996a8bea0da10ad5151f72979',
      });

      // 等待 Loca 加载完成
      const loca = new window.Loca.Container({
        map: map, // 绑定到地图
      });
      loca.ambLight = {
        intensity: 0.4,
        color: '#ced5ed',
      };
      loca.dirLight = {
        intensity: 0.02,
        color: '#666',
        target: [10, 10, 10],
        position: [0, -1, 0.1],
      };
      loca.pointLight = {
        color: 'rgb(155,173,80)',
        position: [120.14133, 30.246611, 20000],
        intensity: 2.2,
        // 距离表示从光源到光照强度为 0 的位置，0 就是光不会消失。
        distance: 40000,
      };

      var geo = new window.Loca.GeoJSONSource({
        data: mockData,
      });

      var ll = new window.Loca.HexagonLayer({
        loca,
        zIndex: 10,
        opacity: 1,
        visible: true,
        zooms: [2, 22],
        acceptLight: true,
      });

      var colors = [
        '#F4FFB3',
        '#BFDDA8',
        '#96CA8D',
        '#75BA89',
        '#5EAC86',
        '#4D9A96',
        '#3F748F',
        '#1D3748',
      ].reverse();
      var heights = [100, 200, 300, 900, 1000, 1200, 1500, 3000];
      ll.setSource(geo);

      // 计算路口rank之和
      function sum(arr: Coordinate[]): number {
        var sum = 0;
        arr.forEach((a: Coordinate) => {
          sum += a.properties.rank;
        });
        return sum;
      }

      ll.setStyle({
        unit: 'meter',
        radius: 120,
        gap: 0,
        altitude: 0,
        height: function (index: number, feature: Feature) {
          var ranks = sum(feature.coordinates);
          return ranks < 20
            ? heights[0]
            : ranks < 40
              ? heights[1]
              : ranks < 60
                ? heights[2]
                : ranks < 80
                  ? heights[3]
                  : ranks < 100
                    ? heights[4]
                    : ranks < 120
                      ? heights[5]
                      : ranks < 130
                        ? heights[6]
                        : heights[7];
        },
        topColor: function (index: number, feature: Feature) {
          var ranks = sum(feature.coordinates);
          return ranks < 20
            ? colors[0]
            : ranks < 40
              ? colors[1]
              : ranks < 60
                ? colors[2]
                : ranks < 80
                  ? colors[3]
                  : ranks < 100
                    ? colors[4]
                    : ranks < 120
                      ? colors[5]
                      : ranks < 130
                        ? colors[6]
                        : colors[7];
        },
        sideBottomColor: function (index: number, feature: Feature) {
          var ranks = sum(feature.coordinates);
          return ranks < 20
            ? colors[0]
            : ranks < 40
              ? colors[1]
              : ranks < 60
                ? colors[2]
                : ranks < 80
                  ? colors[3]
                  : ranks < 100
                    ? colors[4]
                    : ranks < 120
                      ? colors[5]
                      : ranks < 130
                        ? colors[6]
                        : colors[7];
        },
        sideTopColor: function (index: number, feature: Feature) {
          var ranks = sum(feature.coordinates);
          return ranks < 20
            ? colors[0]
            : ranks < 40
              ? colors[1]
              : ranks < 60
                ? colors[2]
                : ranks < 80
                  ? colors[3]
                  : ranks < 100
                    ? colors[4]
                    : ranks < 120
                      ? colors[5]
                      : ranks < 130
                        ? colors[6]
                        : colors[7];
        },
      });
      loca.add(ll);
      // 高度升起动画
      map.on('complete', function () {
        setTimeout(function () {
          ll.show(500);
          ll.addAnimate({
            key: 'height',
            value: [0, 1],
            duration: 500,
            easing: 'Linear',
            transform: 500,
            random: true,
            delay: 10000,
          });
        }, 800);
      });
      loca.animate.start();

      // 图例
      var lengend = new window.Loca.Legend({
        loca: loca,
        title: {
          label: '受骗区域统计',
          fontColor: 'rgba(255,255,255,0.4)',
          fontSize: '16px',
        },
        style: {
          backgroundColor: 'rgba(0,0,0,0.5)',
          left: '20px',
          bottom: '40px',
          fontSize: '12px',
        },
        dataMap: [
          { label: '> 130', color: colors[7] },
          { label: '< 130', color: colors[6] },
          { label: '< 120', color: colors[5] },
          { label: '< 100', color: colors[4] },
          { label: '< 80', color: colors[3] },
          { label: '< 60', color: colors[2] },
          { label: '< 40', color: colors[1] },
          { label: '< 20', color: colors[0] },
        ],
      });
    })
    .catch((e) => {
      console.error(e);
    });
});
</script>

<template>
  <div id="map" class="map-container"></div>
</template>

<style scoped>
.map-container {
  width: 100%;
  height: 100%; /* 确保高度足够显示地图 */
}
</style>
